﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.Threading.Tasks;
using System.Windows.Forms;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows;
using Autodesk.AutoCAD.Geometry;
using System.Data.SQLite;
using System.Data;
using System.Data.Common;
//using Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.PlottingServices;
//using Autodesk.AutoCAD.PlottingServices;
//using Application = Autodesk.AutoCAD.ApplicationServices.Core.Application;
using System.Drawing;
using System.Collections;
using System.Collections.Specialized;
using Autodesk.AutoCAD.Interop;
using Autodesk.AutoCAD.Interop.Common;
using System.Runtime.InteropServices;
using Newtonsoft.Json;
using System.Threading;
using System.ComponentModel;
using System.Diagnostics;

namespace cadbom
{
    class FuYuanProcess
    {
        [DllImport("accore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "acedTrans")]

        static extern int acedTrans(double[] point, IntPtr fromRb, IntPtr toRb, int disp, double[] result);

        List<Dictionary<String, String>> processResultList = new List<Dictionary<string, string>>();
        List<Dictionary<String, String>> titleResultList = new List<Dictionary<string, string>>();
        List<Dictionary<String, Dictionary<String, String>>> productProcessResultList = new List<Dictionary<string, Dictionary<string, string>>>();
        private string selectedProcessName = "";
        private string selectedProductCode = "";
        List<Dictionary<String, Dictionary<String, String>>> processBomResultList = new List<Dictionary<string, Dictionary<string, string>>>();
        NetApi netApi = new NetApi();

        Point3d gblFirst ;
        Point3d gblSecond ;

        public void PlotBlockColToPDF(Point3d first1, Point3d second2, String code)
        {
            String selectedProductCode = code;
            String OutPath = "";
            String processHandleId = "";
            Boolean checkProductCode = false;
            Directory.CreateDirectory(GValues.pdfPath);
            Dictionary<String, Dictionary<String, String>> tableDict = new Dictionary<string, Dictionary<string, string>>();


            Dictionary<String, String> result1 = new Dictionary<string, string>();
            string productcode = "";
            Dictionary<string, Dictionary<string, string>> productProcessResult = new Dictionary<string, Dictionary<string, string>>();

            SetObject setObject = new SetObject();
            setObject.initTableDictData(tableDict);
            // 判断文件是否存在
            //if (File.Exists(OutPath))
            //{
            //    try
            //    {
            //        // 尝试删除文件
            //        File.Delete(OutPath);
            //        outMsg.AddMsg("文件已删除。");
            //    }
            //    catch (IOException ex)
            //    {                    // IO异常处理
            //        outMsg.AddMsg("无法删除文件: " + ex.Message);
            //    }
            //}
            try
            {

                String BlockName;
                String PrinterName = "DWG To PDF.pc3";

                String PaperSize = "ISO_full_bleed_A4_(210.00_x_297.00_MM)";//"ISO_A4_(210.00_x_297.00_MM)";
                Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
                Editor ed = doc.Editor;
                Database db = doc.Database;
                Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("BACKGROUNDPLOT", 0);
                //改成块开始
                //PromptPointOptions ppo = new PromptPointOptions("\nSelect first corner of plot area: ");
                //ppo.AllowNone = false;
                //PromptPointResult ppr = ed.GetPoint(ppo);
                //if (ppr.Status != PromptStatus.OK)
                //    return;
                //Point3d first1 = ppr.Value;
                //PromptCornerOptions pco = new PromptCornerOptions("\nSelect second corner of plot area: ", first1);
                //ppr = ed.GetCorner(pco);
                //if (ppr.Status != PromptStatus.OK)
                //    return;
                //Point3d second2 = ppr.Value;
                //改成块结束

                ///wcs 2 ucs
                ///
                //Vector3d vect = db.Ucsorg.GetVectorTo(new Point3d(0,0,0));
                //Matrix3d matWCS2UCS = Matrix3d.WorldToPlane(vect);
                //Point3d second = second1.TransformBy(matWCS2UCS);
                //Point3d first = first1.TransformBy(matWCS2UCS);
                ////


                //Matrix3d wcs2ucs = doc.Editor.CurrentUserCoordinateSystem.Inverse();
                //Point3d ucsPoint = worldPoint.TransformBy(wcs2ucs);

                //wcs 2 dcs
                //
                //
                // Gets the current view
                //ViewTableRecord acView = doc.Editor.GetCurrentView();
                ////Extents3d eExtents = new Extents3d(new Point3d(0, 0, 0), new Point3d(630, 445.5, 0));
                //Extents3d eExtents = new Extents3d(first, second);
                //// Translates WCS coordinates to DCS
                //Matrix3d matWCS2DCS;
                //matWCS2DCS = Matrix3d.PlaneToWorld(acView.ViewDirection);
                //matWCS2DCS = Matrix3d.Displacement(acView.Target - Point3d.Origin) * matWCS2DCS;
                //matWCS2DCS = Matrix3d.Rotation(-acView.ViewTwist,
                //                               acView.ViewDirection,
                //                               acView.Target) * matWCS2DCS;

                //// Tranforms the extents to DCS
                //matWCS2DCS = matWCS2DCS.Inverse();
                //eExtents.TransformBy(matWCS2DCS);

                //
                //ViewTableRecord acView = doc.Editor.GetCurrentView();

                //Extents3d eExtents = new Extents3d(first, second);

                //// Translates WCS coordinates to DCS
                //Matrix3d matWCS2DCS;
                //matWCS2DCS = Matrix3d.PlaneToWorld(acView.ViewDirection);
                //matWCS2DCS = Matrix3d.Displacement(acView.Target - Point3d.Origin) * matWCS2DCS;
                //matWCS2DCS = Matrix3d.Rotation(-acView.ViewTwist,
                //                                acView.ViewDirection,
                //                                acView.Target) * matWCS2DCS;

                ////Tranforms the extents to DCS
                //matWCS2DCS = matWCS2DCS.Inverse();
                //eExtents.TransformBy(matWCS2DCS);
                //var wcsWindow = new Extents2d(eExtents.MinPoint.X, eExtents.MinPoint.Y,
                //                                        eExtents.MaxPoint.X, eExtents.MaxPoint.Y);

                //
                // 获取当前视图方向
                Vector3d viewDir = ed.CurrentUserCoordinateSystem.CoordinateSystem3d.Zaxis;

                // 获取当前视图位置
                Point3d viewPos = ed.GetCurrentView().Target;

                // 构造视图变换矩阵
                Matrix3d viewTransform = Matrix3d.WorldToPlane(viewDir).Inverse();
                //viewTransform = Matrix3d.Displacement(viewPos.GetAsVector()) * viewTransform;

                //// 将WCS坐标转换为DCS坐标
                Point3d first = first1.TransformBy(viewTransform);
                Point3d second = second2.TransformBy(viewTransform);


                ///====

                // Transform from UCS to DCS
                ResultBuffer rbFrom = new ResultBuffer(new TypedValue(5003, 1)), rbTo = new ResultBuffer(new TypedValue(5003, 2));
                double[] firres = new double[] { 0, 0, 0 };
                double[] secres = new double[] { 0, 0, 0 };
                // Transform the first point...
                acedTrans(first.ToArray(), rbFrom.UnmanagedObject, rbTo.UnmanagedObject, 0, firres);
                // ... and the second
                acedTrans(second.ToArray(), rbFrom.UnmanagedObject, rbTo.UnmanagedObject, 0, secres);
                // We can safely drop the Z-coord at this stage
                Extents2d window = new Extents2d(firres[0], firres[1], secres[0], secres[1]);

                //Object SysVarBackPlot = Application.GetSystemVariable("BACKGROUNDPLOT");
                //Application.SetSystemVariable("BACKGROUNDPLOT", 0);
                Transaction tr = db.TransactionManager.StartTransaction();
                using (tr)
                {
                    // 打开图层表
                    LayerTable lt = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);

                    // 遍历所有图层
                    foreach (ObjectId layerId in lt)
                    {
                        // 打开图层表记录
                        LayerTableRecord ltr = (LayerTableRecord)tr.GetObject(layerId, OpenMode.ForRead);

                        // 检查图层是否锁定
                        if (ltr.IsLocked)
                        {
                            // 解锁图层
                            ltr.UpgradeOpen();
                            ltr.IsLocked = false;
                            ltr.DowngradeOpen();
                        }
                    }
                    // We'll be plotting the current layout
                    BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForRead);

                    // 定义过滤条件，设置仅选择BlockReference

                    //SelectionFilter filter = new SelectionFilter(new TypedValue[]
                    //{
                    //    new TypedValue((int)DxfCode.Start, "TEXT") // "INSERT"代表图块引用
                    //});
                    // 使用选取窗口和过滤条件进行选择
                    PromptSelectionResult selectionResult = ed.SelectCrossingWindow(first, second);

                    // 检查选择结果
                    if (selectionResult.Status != PromptStatus.OK)
                    {
                        ed.WriteMessage("\n未选择对象或操作取消。");
                        return;
                    }
                    //Dictionary<String, String> fieldDict = new Dictionary<string, string>();
                    SelectionSet sSet = selectionResult.Value;
                    ObjectId[] selectedIds = sSet.GetObjectIds();  // 获取选择对象的ObjectiID数组.
                    foreach (ObjectId objId in selectedIds)
                    {
                        Entity entity = tr.GetObject(objId, OpenMode.ForRead) as Entity;
                        if (entity is MText)
                        {

                            MText mtext = entity as MText;
                            //MessageBox.Show(mtext.Text);
                            if (mtext != null)
                            {
                                // 获取 MText 的内容字符串
                                string content = mtext.Text;

                                // AutoCAD 中换行符通常是 \P 或 \N，拆分时都考虑
                                string[] lines = content.Split(new string[] { "\r\n", "\n", "\r" }, StringSplitOptions.None);

                                // 输出每一行内容
                                for (int i = 0; i < lines.Length; i++)
                                {
                                    result1[i.ToString()] = lines[i];
                                    ed.WriteMessage("工艺：" + lines[i]);
                                }
                            }
                        }
                        if (entity is BlockReference)
                        {
                            BlockReference blockRef = entity as BlockReference;
                            // 获取块引用所在的图层
                            string layerName = blockRef.Layer;
                            // 获取块的名称
                            string blockName = blockRef.Name;
                            // 输出块引用的信息
                            ed.WriteMessage("\n在图层 {0} 找到块引用: {1}", layerName, blockName);
                            Dictionary<String, String> result = new Dictionary<string, string>();
                            // 遍历块引用中的所有属性
                            foreach (ObjectId attId in blockRef.AttributeCollection)
                            {
                                AttributeReference attRef = (AttributeReference)tr.GetObject(attId, OpenMode.ForRead);
                                if (attRef.Tag == GValues.BlockField_SemiProductCode) //"零件编号"
                                {
                                    productcode = attRef.TextString;
                                    selectedProductCode = attRef.TextString;
                                }
                                ed.WriteMessage("\n  属性标签: {0}, 属性值: {1}", attRef.Tag, attRef.TextString);
                            }
                            //productProcessResult[productcode] = result;
                            //productProcessResultList.Add(productProcessResult);

                        }

                        if (entity is Table)
                        {

                            Table table = entity as Table;
                            // 你现在可以使用table对象了
                            // ...
                            processHandleId = table.Handle.Value.ToString();
                            if (table.XData != null)
                            {
                                Dictionary<String, String> xDataDict = new Dictionary<string, string>();
                                String tableType = "none";
                                ResultBuffer rb = table.XData; // 获取实体的扩展数据

                                // 遍历ResultBuffer以查看数据
                                foreach (TypedValue tv in rb)
                                {
                                    switch ((DxfCode)tv.TypeCode)
                                    {
                                        case DxfCode.ExtendedDataRegAppName:
                                            var a = tv.Value.ToString();
                                            ed.WriteMessage("\n APP Code :" + a);
                                            break;
                                        case DxfCode.ExtendedDataAsciiString:
                                            var b = tv.Value.ToString();
                                            if (b.IndexOf("tableType:") != -1)
                                            {
                                                String[] cc = b.Split(':');
                                                if (cc[1] == "processSop")
                                                {
                                                    tableType = "processSop";
                                                    xDataDict["processSop"] = "true"; //SOP图纸表格
                                                    xDataDict["tableHandleId"] = processHandleId;
                                                }
                                                if (cc[1] == "processBom")
                                                {
                                                    tableType = "processBom";
                                                    xDataDict["processBom"] = "true"; //工艺图纸表格
                                                    xDataDict["tableHandleId"] = processHandleId;
                                                }
                                                if (cc[1] == "productBom")
                                                {
                                                    tableType = "productBom";
                                                    xDataDict["productBom"] = "true"; //产品图纸表格
                                                    xDataDict["tableHandleId"] = processHandleId;
                                                }
                                            }
                                            else if (b.IndexOf("processName:") != -1)
                                            {
                                                ed.WriteMessage("\n Process Name :" + b);
                                                String[] cc = b.Split(':');
                                                //selectedProcessName = cc[1];
                                                xDataDict["processName"] = cc[1];
                                                xDataDict["tableHandleId"] = processHandleId;
                                            }
                                            else if (b.IndexOf("productCode:") != -1)
                                            {
                                                ed.WriteMessage("\n Product Code :" + b);
                                                String[] cc = b.Split(':');
                                                //selectedProductCode = cc[1];
                                                xDataDict["productCode"] = cc[1];
                                                checkProductCode = true;
                                            }
                                            else
                                            {
                                                ed.WriteMessage("\n Product Code :" + b);
                                                //selectedProductCode = b;
                                                checkProductCode = true;
                                                xDataDict["productCode"] = b;
                                                xDataDict["oldTable"] = "true";
                                                tableType = "oldTable";
                                                xDataDict["tableHandleId"] = processHandleId;
                                            }
                                            break;
                                        // 其他类型的DXF组码...

                                    }
                                }
                                tableDict[tableType] = xDataDict;
                            }
                            else
                            {
                                ed.WriteMessage("\n实体没有扩展数据！");
                            }
                        }

                    }
                    if (!checkProductCode)
                    {
                        ed.WriteMessage("\n选择框内没有定义工艺数据！");
                        //return;
                    }
                    else
                    {
                        if (tableDict["productBom"]["productBom"] == "true" && tableDict["processBom"]["processBom"] == "false" && tableDict["processSop"]["processSop"] == "false")
                        {
                            ed.WriteMessage("\n选择框内没有定义工艺数据！");
                            //return;
                        }
                    }

                    Layout lo = (Layout)tr.GetObject(btr.LayoutId, OpenMode.ForRead);

                    if (PlotFactory.ProcessPlotState == ProcessPlotState.NotPlotting)
                    {
                        PlotEngine pe = PlotFactory.CreatePublishEngine();
                        using (pe)
                        {
                            PlotProgressDialog ppd = new PlotProgressDialog(false, 1, true);
                            using (ppd)
                            {
                                int numSheet = 1;
                                // Setting up the PlotProgress dialog
                                ppd.set_PlotMsgString(PlotMessageIndex.DialogTitle, "Custom Plot Progress");
                                ppd.set_PlotMsgString(PlotMessageIndex.CancelJobButtonMessage, "Cancel Job");
                                ppd.set_PlotMsgString(PlotMessageIndex.CancelSheetButtonMessage, "Cancel Sheet");
                                ppd.set_PlotMsgString(PlotMessageIndex.SheetSetProgressCaption, "Sheet Set Progress");
                                ppd.set_PlotMsgString(PlotMessageIndex.SheetProgressCaption, "Sheet Progress");
                                ppd.LowerPlotProgressRange = 0;
                                ppd.UpperPlotProgressRange = 100;
                                ppd.PlotProgressPos = 0;


                                ppd.OnBeginPlot();
                                ppd.IsVisible = true;
                                pe.BeginPlot(ppd, null);

                                ppd.StatusMsgString = "Plotting block 1";
                                ppd.OnBeginSheet(); //????
                                ppd.LowerSheetProgressRange = 0;
                                ppd.UpperSheetProgressRange = 100;
                                ppd.SheetProgressPos = 0;

                                PlotInfoValidator piv = new PlotInfoValidator();
                                piv.MediaMatchingPolicy = MatchingPolicy.MatchEnabled;
                                PlotPageInfo ppi = new PlotPageInfo();
                                PlotInfo pi = new PlotInfo();
                                //BlockReference blk = gblk.BlockRef;
                                //Layout lo = btr.LayoutObj;

                                //// Getting coodinates of window to plot
                                //Extents3d ext = (Extents3d)blk.Bounds;
                                //Point3d first = ext.MaxPoint;
                                //Point3d second = ext.MinPoint;
                                //ResultBuffer rbFrom = new ResultBuffer(new TypedValue(5003, 1)), rbTo = new ResultBuffer(new TypedValue(5003, 2));
                                //double[] firres = new double[] { 0, 0, 0 };
                                //double[] secres = new double[] { 0, 0, 0 };
                                //acedTrans(first.ToArray(), rbFrom.UnmanagedObject, rbTo.UnmanagedObject, 0, firres);
                                //acedTrans(second.ToArray(), rbFrom.UnmanagedObject, rbTo.UnmanagedObject, 0, secres);
                                //Extents2d window = new Extents2d(firres[0], firres[1], secres[0], secres[1]);

                                // We need a PlotSettings object based on the layout settings which we then customize
                                PlotSettings ps = new PlotSettings(lo.ModelType);
                                //ps.PlotPlotStyles = true;
                                // Specify the plot options

                                LayoutManager.Current.CurrentLayout = lo.LayoutName;
                                pi.Layout = lo.Id;
                                ps.CopyFrom(lo);
                                ps.PrintLineweights = true;
                                ps.PlotTransparency = false;
                                ps.PlotPlotStyles = true;
                                ps.DrawViewportsFirst = true;
                                ps.ShowPlotStyles = true;
                                //PlotStyleTable = GetVauleFromArray("CtbThinnerLinesName")
                                // The PlotSettingsValidator helps create a valid PlotSettings object
                                PlotSettingsValidator psv = PlotSettingsValidator.Current;
                                psv.SetPlotConfigurationName(ps, PrinterName, PaperSize);
                                psv.RefreshLists(ps);
                                psv.SetPlotWindowArea(ps, window);
                                psv.SetPlotType(ps, Autodesk.AutoCAD.DatabaseServices.PlotType.Window);
                                psv.SetUseStandardScale(ps, true);
                                psv.SetStdScaleType(ps, StdScaleType.ScaleToFit);
                                psv.SetPlotRotation(ps, PlotRotation.Degrees090);
                                psv.SetCurrentStyleSheet(ps, "monochrome.ctb");
                                ////
                                //var e = Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("PSTYLEMODE");
                                //var a = db.PlotStyleMode;
                                //var b = psv.GetPlotStyleSheetList();
                                //foreach (String CTB in b)
                                //{
                                //    var c = CTB;
                                //}
                                //if (a)
                                //{
                                //     psv.SetCurrentStyleSheet(ps, "monochrome.ctb");

                                //}
                                //else
                                //{
                                //    psv.SetCurrentStyleSheet(ps, "monochrome.stb");
                                //}


                                psv.SetPlotCentered(ps, true);

                                pi.OverrideSettings = ps;
                                piv.Validate(pi);
                                //if (selectedProcessName != "")
                                //{
                                //    OutPath = GValues.pdfPath + "\\" + selectedProductCode + "-process-" + selectedProcessName + "-" + tableDict["processSop"]["tableHandleId"] + ".pdf";
                                //}
                                //else
                                //{
                                //    OutPath = GValues.pdfPath + "\\" + selectedProductCode + ".pdf";
                                //}
                                OutPath = GValues.pdfPath + "\\" + selectedProductCode + ".pdf";
                                pe.BeginDocument(pi, doc.Name, null, 1, true, OutPath); // Create document for the first page

                                // Plot the window
                                pe.BeginPage(ppi, pi, true, null);
                                pe.BeginGenerateGraphics(null);
                                ppd.SheetProgressPos = 50;
                                pe.EndGenerateGraphics(null);

                                // Finish the sheet
                                pe.EndPage(null);
                                ppd.SheetProgressPos = 100;
                                ppd.PlotProgressPos = 100; //+= Convert.ToInt32(100 / BlocksToPlot.Count);
                                ppd.OnEndSheet();
                                // Finish the document and finish the plot
                                pe.EndDocument(null);

                                ppd.PlotProgressPos = 100;
                                ppd.OnEndPlot();
                                pe.EndPlot(null);
                                ed.WriteMessage("\nPlot completed successfully!\n\n");
                                ps.Dispose();
                                pe.Dispose();
                                ppd.Dispose();
                            }
                        }
                        //Task.Delay(2000);

                        //doc.CloseAndDiscard();

                        // 关闭绘图过程
                        //PlotFactory.ProcessPlotState = PlotState.Cancel;
                    }
                    else
                    {
                        ed.WriteMessage("\nAnother plot is in progress.\n\n");
                    }
                    tr.Commit();
                    tr.Dispose();
                    //Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.PlotSettings): DisposableWrapper
                    //Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.ViewTableRecord): DisposableWrapper

                }
                productProcessResult[productcode] = result1;
                processBomResultList.Add(productProcessResult);
                //Application.SetSystemVariable("BACKGROUNDPLOT", SysVarBackPlot);
                //if (this.pdfform != null)
                //{
                //    this.pdfform.Close();
                //    this.pdfform = null;

                //}
                //pdfform = new PdfProgressForm(selectedProductCode, new Action<int>((r) =>
                //{
                //    if (r == 1)
                //    {
                //        //uploadPdf();
                //        //this.pdfform.Close();
                //    }
                //    else
                //    {
                //        //ed.WriteMessage("\n上传pdf失败");
                //    }
                //}));
                //// 显示 Windows Form 窗口
                //Autodesk.AutoCAD.ApplicationServices.Application.ShowModelessDialog(null, pdfform);
                //pdfform.beginProcess();

                //for (int i = 0; i <= 100; i++)
                //{
                //    SimpleProgressBar bar = new SimpleProgressBar();
                //    bar.Show();
                //    bar.UpdateProgress(100);

                //    //Thread.Sleep(100); // 模拟任务的执行时间
                //    Task.Delay(TimeSpan.FromSeconds(2)).Wait(); //等待2秒
                //    String filePath = GValues.pdfPath + "\\selectDWGWindow.pdf";
                //    // 判断文件是否存在
                //    if (File.Exists(filePath))
                //    {
                //        bar.Close();
                //        DialogResult res = MessageBox.Show("PDF文件已经生成，确认要上传吗？", "上传提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                //        if (res == DialogResult.OK)  //1为确定，2为取消,...
                //        {
                //            //按OK后，执行语句；
                //            if (checkProductCode)
                //            {
                //                uploadPdf();
                //            }
                //        }
                //        if (res == DialogResult.Cancel)  //1为确定，2为取消,...
                //        {
                //            //按Cancel后，执行语句；
                //        }

                //        break;
                //        //Thread.Sleep(2000);
                //        //uploadPdf();
                //        //ed.WriteMessage("上传完成！");
                //    }
                // }

            }
            catch (Autodesk.AutoCAD.Runtime.Exception e)
            {

            }
            finally
            {

            }



        }
        public void ExecuteLisp(Action<String> callback)
        {
            // 获取当前文档和数据库
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            // 定义文件路径
            string filePath = @"C:\erptestdll\block_corners.txt";

            // 检查文件是否存在
            if (File.Exists(filePath))
            {
                // 如果文件存在，则删除
                File.Delete(filePath);
            }

            // 定义要执行的LISP语句
            string lispCode = @"(defun c:GetBlockCornersall (/ ss i ent obj minpt maxpt file)
    (vl-load-com) ; 确保 ActiveX 支持已加载
    ; 创建选择集，过滤出所有名为 ""图框"" 的块参照
    (setq ss (ssget ""_X"" '((0 . ""INSERT"") (2 . ""图框"")))) 

    (cond
        ((not ss)
            (princ ""\n未找到名为 图框 的块参照。""))
        
        (T
            ; 打开文件以写入坐标信息
            (setq file (open ""C:/erptestdll/block_corners.txt"" ""w""))
            (if file
                (progn
                    ; 遍历选择集中的每个块参照
                    (repeat (setq i (sslength ss))
                        (setq ent (ssname ss (setq i (1- i)))) ; 获取当前块参照的实体名
                        (setq obj (vlax-ename->vla-object ent)) ; 转换为 VLA 对象
                        (vla-GetBoundingBox obj 'minpt 'maxpt) ; 获取边界框
                        
                        (setq
                            minpt (vlax-safearray->list minpt) ; 转换最小点坐标
                            maxpt (vlax-safearray->list maxpt) ; 转换最大点坐标
                        )
                        
                        (princ (strcat ""\n块 "" (vla-get-name obj) "" 的左下角坐标: "" (rtos (car minpt) 2 2) "", "" (rtos (cadr minpt) 2 2)) file)
                        (princ (strcat ""\n块 "" (vla-get-name obj) "" 的右上角坐标: "" (rtos (car maxpt) 2 2) "", "" (rtos (cadr maxpt) 2 2)) file)
                        (princ (strcat ""\n块 "" (vla-get-name obj) "" 的左下角坐标: "" (rtos (car minpt) 2 2) "", "" (rtos (cadr minpt) 2 2)))
                        (princ (strcat ""\n块 "" (vla-get-name obj) "" 的右上角坐标: "" (rtos (car maxpt) 2 2) "", "" (rtos (cadr maxpt) 2 2)))
                    )
                    ; 关闭文件
                    (close file)
                )
                (princ ""\n无法打开文件进行写入操作。"")
            )
        )
    )
    (princ)
)
(c:GetBlockCornersall)";

            try
            {
                // 获取 CMDECHO 系统变量的值
                ResultBuffer rb = Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("CMDECHO") as ResultBuffer;
                int oldCmdecho = 0;
                if (rb != null)
                {
                    foreach (TypedValue tv in rb)
                    {
                        if (tv.TypeCode == (int)DxfCode.Int32)
                        {
                            oldCmdecho = (int)tv.Value;
                            break;
                        }
                    }
                }

                // 关闭命令行回显
                Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("CMDECHO", 0);

                // 执行LISP语句
                Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.SendStringToExecute(lispCode + "\n", true, false, false);


                // 恢复命令行回显
                Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("CMDECHO", oldCmdecho);
                // 启动新任务检查文件
                Task.Run(() => CheckFileExists(filePath, callback));

                ed.WriteMessage("\nLISP语句执行成功！");
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage("\n执行LISP语句时出错: " + ex.Message);
            }
        }
        private void CheckFileExists(string filePath, Action<String> callback)
        {
            // 循环检查文件是否存在，最多检查 10 次
            for (int i = 0; i < 10; i++)
            {
                // 检查文件是否存在
                if (File.Exists(filePath))
                {
                    if (callback != null)
                    {
                        callback.Invoke("ok");
                    }
                    return; // 如果文件存在，退出方法
                }
                else
                {
                    Console.WriteLine("文件不存在，等待 5 秒后重试...");
                }

                // 暂停 5 秒
                Thread.Sleep(5000);
            }
        }
        public void updateCadProductCode(List<BasProduct> productList, Action<String> callback)
        {
            // 获取当前文档和数据库
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            DocumentLock docLock = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument();
            productProcessResultList = new List<Dictionary<string, Dictionary<string, string>>>();
            List<Extents3d> extends = readPointData();
            // 启动事务
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                // 打开图层表
                LayerTable lt = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);

                // 遍历所有图层
                foreach (ObjectId layerId in lt)
                {
                    // 打开图层表记录
                    LayerTableRecord ltr = (LayerTableRecord)tr.GetObject(layerId, OpenMode.ForRead);

                    // 检查图层是否锁定
                    if (ltr.IsLocked)
                    {
                        // 解锁图层
                        ltr.UpgradeOpen();
                        ltr.IsLocked = false;
                        ltr.DowngradeOpen();
                    }
                }

                productList.ForEach(p =>
                {

                    string handle = p.cadHandleId;
                    if (handle != null)
                    {
                        ObjectId objId = db.GetObjectId(false, new Handle(long.Parse(handle)), 0);

                        if (!objId.IsNull)
                        {
                            Entity entity = (Entity)tr.GetObject(objId, OpenMode.ForWrite);
                            if (entity is BlockReference)
                            {
                                BlockReference blockRef = entity as BlockReference;
                                // 获取块引用所在的图层
                                string layerName = blockRef.Layer;
                                // 获取块的名称
                                string blockName = blockRef.Name;
                                // 输出块引用的信息
                                ed.WriteMessage("\n在图层 {0} 找到块引用: {1}", layerName, blockName);
                                Dictionary<string, Dictionary<string, string>> productProcessResult = new Dictionary<string, Dictionary<string, string>>();
                                Dictionary<String, String> result = new Dictionary<string, string>();
                                string productcode = "";
                                // 遍历块引用中的所有属性
                                foreach (ObjectId attId in blockRef.AttributeCollection)
                                {
                                    AttributeReference attRef = (AttributeReference)tr.GetObject(attId, OpenMode.ForWrite);

                                    if (attRef.Tag == GValues.BlockField_SemiProductCode ) //"零件编号"
                                    {
                                        if (p.code != null)
                                        {
                                            attRef.TextString = p.code;
                                        }
                                       
                                    }
                                    ed.WriteMessage("\n  属性标签: {0}, 属性值: {1}", attRef.Tag, attRef.TextString);
                                }

                            }
                        }
                        else
                        {
                            ed.WriteMessage("\n未找到与指定 Handle ID 对应的对象。");
                        }
                    }
                });


                docLock.Dispose();
                // 提交事务
                tr.Commit();
            }
            callback.Invoke("ok");
        }
        public void UnlockAllLayersAndReadObject(Action<List<Dictionary<String, Dictionary<String, String>>>> callback)
        {
            // 获取当前文档和数据库
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            DocumentLock docLock = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument();
            productProcessResultList = new List<Dictionary<string, Dictionary<string, string>>>() ;
            List<Extents3d> extends = readPointData();
            // 启动事务
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                // 打开图层表
                LayerTable lt = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);

                // 遍历所有图层
                foreach (ObjectId layerId in lt)
                {
                    // 打开图层表记录
                    LayerTableRecord ltr = (LayerTableRecord)tr.GetObject(layerId, OpenMode.ForRead);

                    // 检查图层是否锁定
                    if (ltr.IsLocked)
                    {
                        // 解锁图层
                        ltr.UpgradeOpen();
                        ltr.IsLocked = false;
                        ltr.DowngradeOpen();
                    }
                }

                // 打开块表
                BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);

                // 打开模型空间块表记录
                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);
                // 打开对象以读取其属性
                // 遍历模型空间中的所有对象，选择所有块参照
                foreach (ObjectId objId in btr)
                {
                    Entity entity = (Entity)tr.GetObject(objId, OpenMode.ForWrite);
                    if (entity is MText)
                    {
                        MText mtext = entity as MText;
                        //MessageBox.Show(mText.Text);
                         if (mtext != null)
                        {
                            // 获取 MText 的内容字符串
                            string content = mtext.Text;

                            // AutoCAD 中换行符通常是 \P 或 \N，拆分时都考虑
                            string[] lines = content.Split(new string[] { "\\P", "\\N" }, StringSplitOptions.None);

                            // 输出每一行内容
                            for (int i = 0; i < lines.Length; i++)
                            {
                                ed.WriteMessage("工艺：" + lines[i]);
                            }
                        }
                    }
                    if (entity is BlockReference)
                    {
                        BlockReference blockRef = entity as BlockReference;                       
                        // 获取块引用所在的图层
                        string layerName = blockRef.Layer;
                        // 获取块的名称
                        string blockName = blockRef.Name;
                        // 输出块引用的信息
                        ed.WriteMessage("\n在图层 {0} 找到块引用: {1}", layerName, blockName);
                        Dictionary<string, Dictionary<string, string>> productProcessResult = new Dictionary<string, Dictionary<string, string>>();
                        Dictionary<String, String> result = new Dictionary<string, string>();
                        string productcode = "";
                        // 遍历块引用中的所有属性
                        foreach (ObjectId attId in blockRef.AttributeCollection)
                        {
                            AttributeReference attRef = (AttributeReference)tr.GetObject(attId, OpenMode.ForWrite);
                            if (attRef.Tag == GValues.BlockField_CustName) //"客户编号"
                            {
                                result[attRef.Tag] = attRef.TextString;
                            }
                            if (attRef.Tag == GValues.BlockField_SemiProductCode) // "零件编号"
                            {
                                result[attRef.Tag] = attRef.TextString;
                            }
                            if (attRef.Tag == GValues.BlockField_Project) //"项目"
                            {
                                result[attRef.Tag] = attRef.TextString;
                            }
                            if (attRef.Tag == GValues.BlockField_SurfaceChuli) // "表面处理"
                            {
                                result[attRef.Tag] = attRef.TextString;
                            }
                            if (attRef.Tag == GValues.BlockField_SemiProductName ) //"零件名称"
                            {
                                productcode = attRef.TextString;
                            }
                            ed.WriteMessage("\n  属性标签: {0}, 属性值: {1}", attRef.Tag, attRef.TextString);
                        }
                        result["handleid"] = blockRef.Handle.Value.ToString();
                        productProcessResult[productcode] = result;
                        productProcessResultList.Add(productProcessResult);

                    }
                }

                docLock.Dispose();
                // 提交事务
                tr.Commit();
            }
            callback.Invoke(productProcessResultList);
        }

        public void createProcessBom(Action<List<Dictionary<String, Dictionary<String, String>>>> callback)
        {
            // 获取当前文档和数据库
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            DocumentLock docLock = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument();

            List<Extents3d> extends = readPointData();
            // 启动事务
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                // 打开图层表
                LayerTable lt = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);

                // 遍历所有图层
                foreach (ObjectId layerId in lt)
                {
                    // 打开图层表记录
                    LayerTableRecord ltr = (LayerTableRecord)tr.GetObject(layerId, OpenMode.ForRead);

                    // 检查图层是否锁定
                    if (ltr.IsLocked)
                    {
                        // 解锁图层
                        ltr.UpgradeOpen();
                        ltr.IsLocked = false;
                        ltr.DowngradeOpen();
                    }
                }
                int i = 0;
                extends.ForEach(p =>
                {
                    i++;
                    PlotBlockColToPDF(p.MinPoint, p.MaxPoint, "code" + i);

                });

                docLock.Dispose();
                // 提交事务
                tr.Commit();
            }
            //processResultList.AddRange(titleResultList);
            callback.Invoke(processBomResultList);
        }


        private List<Extents3d> readPointData()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Editor editor = doc.Editor;
            // 指定配置文件的路径
            string configFilePath = @"C:\erptestdll\block_corners.txt"; //"E:\\Program Files\\Autodesk\\AutoCAD 2014\\erptestdll\\config.txt";
            List<Extents3d> extents = new List<Extents3d>();
            try
            {
                // 读取文本文件的所有行
                string[] lines = File.ReadAllLines(configFilePath);

                // 遍历每一行并处理配置信息
                int i = 0;
                string[] pointA = null;
                string[] pointB = null;
                foreach (string line in lines)
                {
                    if (line.IndexOf(":") != -1)
                    {
                        i++;
                        // 假设配置文件的每一行都是以"键=值"的格式存储
                        string[] keyValue = line.Split(':');
                        if (keyValue.Length == 2)
                        {
                            string key = keyValue[0].Trim();
                            string value = keyValue[1].Trim();

                            try
                            {

                                if (i % 2 == 1)
                                {
                                    pointA = value.Split(',');
                                }
                                else
                                {
                                    pointB = value.Split(',');
                                    Point3d first = new Point3d(Double.Parse(pointA[0]), Double.Parse(pointA[1]), 0);
                                    Point3d second = new Point3d(Double.Parse(pointB[0]), Double.Parse(pointB[1]), 0);
                                    Extents3d extent = new Extents3d(first, second);
                                    extents.Add(extent);
                                    //SelectBlock2Pdf toPdf = new SelectBlock2Pdf();
                                    //toPdf.PlotBlockColToPDF(first, second, "code" + i);
                                }
                            }
                            catch (System.Exception e)
                            {
                                editor.WriteMessage(e.ToString());
                            }
                        }
                    } //判断正常的行
                }
            }
            catch (IOException e)
            {
                editor.WriteMessage("读取配置文件时发生错误: " + e.Message);
            }
            return extents;
        }

        public void SelectAndFind()
        {
            List<Extents3d> extends = readPointData();
            extends.ForEach(p =>
            {
                FindMTextAndBlock(p.MinPoint, p.MaxPoint);
            });
        }

         public void FindMTextAndBlock(Point3d pt1, Point3d pt2)
        {
            // 获取当前文档和编辑器
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;

            // 创建一个窗口选择过滤器
            SelectionFilter filter = new SelectionFilter(new TypedValue[] { new TypedValue(0, "TEXT,MTEXT,INSERT") });
            PromptSelectionResult psr = ed.SelectWindow(pt1, pt2, filter);

            if (psr.Status != PromptStatus.OK)
            {
                ed.WriteMessage("\n选择失败！");
                return;
            }

            // 遍历选择集
            using (Transaction tr = doc.TransactionManager.StartTransaction())
            {
                List<string> mTextContents = new List<string>();
                List<string> blockNames = new List<string>();

                foreach (ObjectId id in psr.Value.GetObjectIds())
                {
                    Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;
                    if (ent is MText)
                    {
                        MText mtext = ent as MText;
                        mTextContents.Add(mtext.Text);
                        ed.WriteMessage("\n找到 MText:"+mtext.Text);
                    }
                    else if (ent is BlockReference)
                    {
                        BlockReference blockRef = ent as BlockReference;
                        blockNames.Add(blockRef.Name);
                        ed.WriteMessage("\n找到 Block: " +blockRef.Name);

                        foreach (ObjectId attId in blockRef.AttributeCollection)
                        {
                            AttributeReference attRef = (AttributeReference)tr.GetObject(attId, OpenMode.ForRead);
                            if (attRef.Tag == GValues.BlockField_SemiProductCode) //"零件编号"
                            {
                                ed.WriteMessage("\n  产品标签: {0}, 属性值: {1}", attRef.Tag, attRef.TextString);
                            }
                            ed.WriteMessage("\n  属性标签: {0}, 属性值: {1}", attRef.Tag, attRef.TextString);
                        }
                    }
                }

                // 提交事务
                tr.Commit();

                // 输出结果（可以根据需要返回或处理这些数据）
                ed.WriteMessage("\n找到的 MText 内容：");
                foreach (var content in mTextContents)
                {
                    ed.WriteMessage("\n" + content);
                }

                ed.WriteMessage("\n找到的 Block 名称：");
                foreach (var name in blockNames)
                {
                    ed.WriteMessage("\n" + name);
                }
            }
        }

         public void SelectAndCopyToNewDwg()
    {
        Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
        Editor ed = doc.Editor;
        Database db = doc.Database;

        try
        {
            // 1. 用户输入对角点，创建选择窗口
            PromptPointResult ppr1 = ed.GetPoint("\n请输入第一个对角点: ");
            if (ppr1.Status != PromptStatus.OK) return;

            PromptPointOptions ppo2 = new PromptPointOptions("\n请输入第二个对角点: ");
            ppo2.BasePoint = ppr1.Value;
            ppo2.UseBasePoint = true;
            PromptPointResult ppr2 = ed.GetPoint(ppo2);
            if (ppr2.Status != PromptStatus.OK) return;

            Point3d pt1 = ppr1.Value;
            Point3d pt2 = ppr2.Value;

            Extents3d window = new Extents3d(
                new Point3d(Math.Min(pt1.X, pt2.X), Math.Min(pt1.Y, pt2.Y), Math.Min(pt1.Z, pt2.Z)),
                new Point3d(Math.Max(pt1.X, pt2.X), Math.Max(pt1.Y, pt2.Y), Math.Max(pt1.Z, pt2.Z))
            );

            // 2. 选择窗口内所有对象
            PromptSelectionResult psr = ed.SelectCrossingWindow(window.MinPoint, window.MaxPoint);
            if (psr.Status != PromptStatus.OK)
            {
                ed.WriteMessage("\n未选择到任何对象。");
                return;
            }

            ObjectId[] selectedIds = psr.Value.GetObjectIds();

            if (selectedIds.Length == 0)
            {
                ed.WriteMessage("\n选择集为空。");
                return;
            }

            // 3. 保存选中对象的 Handle 到文件
            string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            string handleFilePath = Path.Combine(desktopPath, "SelectedHandles.txt");

            using (StreamWriter sw = new StreamWriter(handleFilePath, false))
            {
                foreach (ObjectId id in selectedIds)
                {
                    // 保存 Handle 字符串
                    sw.WriteLine(id.Handle.ToString());
                }
            }
            ed.WriteMessage("\n已保存 {selectedIds.Length} 个对象的 Handle 到文件: {handleFilePath}");

            // 4. 创建新数据库，复制对象
            string newDwgPath = Path.Combine(desktopPath, "CopiedObjects.dwg");

            // 新建一个空数据库
            using (Database newDb = new Database(true, true))
            {
                // 5. 读取 Handle 文件，转换为 ObjectId
                List<ObjectId> idsToCopy = new List<ObjectId>();
                using (StreamReader sr = new StreamReader(handleFilePath))
                {
                    string line;
                    while ((line = sr.ReadLine()) != null)
                    {
                        Handle h = new Handle(Convert.ToInt64(line, 16)); // Handle是16进制字符串
                        ObjectId id = db.GetObjectId(false, h, 0);
                        if (!id.IsNull && !id.IsErased)
                        {
                            idsToCopy.Add(id);
                        }
                    }
                }

                if (idsToCopy.Count == 0)
                {
                    ed.WriteMessage("\n根据 Handle 未找到任何有效对象。");
                    return;
                }

                // 转换 List<ObjectId> 到 ObjectIdCollection
                ObjectIdCollection idsToCopyCollection = new ObjectIdCollection();
                foreach (ObjectId id in idsToCopy)
                {
                    idsToCopyCollection.Add(id);
                }
                // 6. 使用 WblockCloneObjects 复制对象到新数据库
                IdMapping mapping = new IdMapping();
                db.WblockCloneObjects(
                    idsToCopyCollection,
                    newDb.CurrentSpaceId,
                    mapping,
                    DuplicateRecordCloning.Replace,
                    false
                );

                // 7. 保存新DWG文件
                newDb.SaveAs(newDwgPath, DwgVersion.Current);
                ed.WriteMessage("\n成功复制 {idsToCopy.Count} 个对象到新文件: {newDwgPath}");
            }
        }
        catch (System.Exception ex)
        {
            ed.WriteMessage("\n发生异常: {ex.Message}");
        }
    }
         // 辅助方法：获取指定范围内的所有对象ID
         private void GetObjectsWithinBounds(Database db)
{
    ObjectIdCollection objectIds = new ObjectIdCollection();
    Extents3d extents = new Extents3d();
    using (Transaction tr = db.TransactionManager.StartTransaction())
    {
        BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
        BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);
        foreach (ObjectId objId in btr)
        {
            Entity ent = tr.GetObject(objId, OpenMode.ForRead) as Entity;
            if (ent is BlockReference)
            {
                BlockReference blockRef = ent as BlockReference;
                gblFirst = blockRef.DynamicBlockTableRecord.Database.Extmin;
                gblSecond = blockRef.DynamicBlockTableRecord.Database.Extmax;
                //extents = new Extents3d(first,second);
            }
        }
        tr.Commit();
    }
    //return extents;
}
         // 辅助方法：获取模型空间中的所有对象ID
         private ObjectIdCollection GetAllObjectIds(Database db)
         {
             ObjectIdCollection objectIds = new ObjectIdCollection();
             using (Transaction tr = db.TransactionManager.StartTransaction())
             {
                 BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                 BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);

                 foreach (ObjectId objId in btr)
                 {
                     objectIds.Add(objId);
                 }
                 tr.Commit();
             }
             return objectIds;
         }
        public void GeneratePDFWithParams()
{
    // 参数：DWG文件路径和对角坐标
    string dwgFilePath = @"d:\工程图\11HZXC304-6.dwg"; // 替换为你的DWG文件路径
    Point3d corner1 = new Point3d(0, 0, 0); // 替换为你的对角坐标1
    Point3d corner2 = new Point3d(100, 100, 0); // 替换为你的对角坐标2
    string outputPdfPath = @"C:\path\to\output\file.pdf"; // 替换为你的PDF输出路径
    // 打开DWG文件
    Database db = new Database(false, true);
    // 提示用户PDF已生成
    Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
    try
    {

        db.ReadDwgFile(dwgFilePath, FileShare.ReadWrite, true, "");

        // 获取要导出的对象ID集合
        GetObjectsWithinBounds(db);

        ed.WriteMessage("坐标第一:{0}，第二:{1}", gblFirst, gblSecond);
        //Point3d first = extends.MinPoint;//new Point3d(45334.83,27504.64,0);
        //Point3d second = extends.MaxPoint; //new Point3d(43506.97,26230.83,0);
        PlotBlockColToPDF(gblFirst, gblSecond, "10000");
        ed.WriteMessage("\nPDF已成功生成到: {outputPdfPath}");

        // 处理数据库对象，确保正确关闭文件
        db.Dispose();
    }
    catch (Autodesk.AutoCAD.Runtime.Exception ex)
    {
       
        ed.WriteMessage("\n发生错误: " + ex.Message);

        // 如果发生异常，确保数据库对象被正确释放
        if (db != null)
        {
            db.Dispose();
        }
    }
}

        public void ExtractIdsAndSave()
        {
            // 指定 DWG 文件路径
            string dwgFilePath = @"d:\工程图\11HZXC304-1.dwg";
            // 指定保存 ID 的文件路径
            string idFilePath = @"C:\temp\Ids.txt";

            // 打开 DWG 文件
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.Open(dwgFilePath, false);
            Database db = doc.Database;
            Editor ed = doc.Editor;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);

                using (StreamWriter writer = new StreamWriter(idFilePath))
                {
                    foreach (ObjectId objId in btr)
                    {
                        writer.WriteLine(objId.ToString());
                    }
                }

                tr.Commit();
            }

            // 关闭 DWG 文件
            doc.CloseAndDiscard();
        }


    //     private void PlotToPdf(Database db, string pdfFilePath)
    //{
    //    using (PlotEngine pe = PlotFactory.CreatePublishEngine())
    //    {
    //        PlotProgressDialog ppd = new PlotProgressDialog(false, 1, true);
    //        ppd.set_PlotMsgString(PlotMessageIndex.DialogTitle, "正在生成PDF");
    //        ppd.set_PlotMsgString(PlotMessageIndex.CancelJobButtonMessage, "取消");
    //        ppd.set_PlotMsgString(PlotMessageIndex.CancelSheetButtonMessage, "取消");
    //        ppd.set_PlotMsgString(PlotMessageIndex.SheetSetProgressCaption, "进度");
    //        ppd.set_PlotMsgString(PlotMessageIndex.SheetProgressCaption, "进度");
    //        ppd.LowerPlotProgressRange = 0;
    //        ppd.UpperPlotProgressRange = 100;
    //        ppd.PlotProgressPos = 0;
    //        ppd.OnBeginPlot();
    //        ppd.IsVisible = true;
    //        ppd.OnBeginSheet();
    //        ppd.SheetProgressPos = 0;

    //        PlotInfo pi = new PlotInfo();
    //        pi.Layout = db.CurrentSpaceId;

    //        PlotSettings ps = new PlotSettings(db.CurrentSpaceId);
    //        ps.CopyFrom(db.PlotSettingsDictionaryId.GetObject(OpenMode.ForRead) as PlotSettings);

    //        // 设置打印机为PDF
    //        PlotSettingsValidator psv = PlotSettingsValidator.Current;
    //        psv.SetPlotConfigurationName(ps, "DWG To PDF.pc3", "ISO_full_bleed_A4_(210.00 x 297.00 MM)");
    //        psv.RefreshLists(ps);
    //        psv.SetPlotType(ps, PlotType.Extents);
    //        psv.SetUseStandardScale(ps, true);
    //        psv.SetStdScaleType(ps, StdScaleType.ScaleToFit);
    //        psv.SetPlotCentered(ps, true);

    //        pi.OverrideSettings = ps;

    //        if (PlotFactory.ProcessPlotState == ProcessPlotState.NotPlotting)
    //        {
    //            pe.BeginPlot(ppd, null);
    //            pe.BeginDocument(pi, db.Filename, null, 1, true, pdfFilePath);
    //            pe.BeginPage(new PlotPageInfo());
    //            pe.BeginGenerateGraphics(null);
    //            pe.EndGenerateGraphics(null);
    //            pe.EndPage(null);
    //            pe.EndDocument(null);
    //            pe.EndPlot(null);
    //        }

    //        ppd.OnEndSheet();
    //        ppd.OnEndPlot();
    //        ppd.Dispose();
    //    }
    //}


        public void BlockToPdf()
        {
            netApi.InitDomainConfig();
            netApi.getUserInfo();
            Dictionary<String, String> result = new Dictionary<string, string>();
            String OutPath = "";
            String processHandleId = "";
            Boolean checkProductCode = false;
            Directory.CreateDirectory(GValues.pdfPath);
            Dictionary<String, Dictionary<String, String>> tableDict = new Dictionary<string, Dictionary<string, string>>();
            SetObject setObject = new SetObject();
            setObject.initTableDictData(tableDict);
            try
            {

                String BlockName;
                String PrinterName = "DWG To PDF.pc3";

                String PaperSize = "ISO_full_bleed_A4_(210.00_x_297.00_MM)";//"ISO_A4_(210.00_x_297.00_MM)";
                Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
                Editor ed = doc.Editor;
                Database db = doc.Database;
                Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("BACKGROUNDPLOT", 0);
                PromptPointOptions ppo = new PromptPointOptions("\nSelect first corner of plot area: ");
                ppo.AllowNone = false;
                PromptPointResult ppr = ed.GetPoint(ppo);
                if (ppr.Status != PromptStatus.OK)
                    return;
                Point3d first1 = ppr.Value;
                PromptCornerOptions pco = new PromptCornerOptions("\nSelect second corner of plot area: ", first1);
                ppr = ed.GetCorner(pco);
                if (ppr.Status != PromptStatus.OK)
                    return;
                Point3d second2 = ppr.Value;

                //
                // 获取当前视图方向
                Vector3d viewDir = ed.CurrentUserCoordinateSystem.CoordinateSystem3d.Zaxis;

                // 获取当前视图位置
                Point3d viewPos = ed.GetCurrentView().Target;

                // 构造视图变换矩阵
                Matrix3d viewTransform = Matrix3d.WorldToPlane(viewDir).Inverse();
                //viewTransform = Matrix3d.Displacement(viewPos.GetAsVector()) * viewTransform;

                //// 将WCS坐标转换为DCS坐标
                Point3d first = first1.TransformBy(viewTransform);
                Point3d second = second2.TransformBy(viewTransform);


                ///====

                // Transform from UCS to DCS
                ResultBuffer rbFrom = new ResultBuffer(new TypedValue(5003, 1)), rbTo = new ResultBuffer(new TypedValue(5003, 2));
                double[] firres = new double[] { 0, 0, 0 };
                double[] secres = new double[] { 0, 0, 0 };
                // Transform the first point...
                acedTrans(first.ToArray(), rbFrom.UnmanagedObject, rbTo.UnmanagedObject, 0, firres);
                // ... and the second
                acedTrans(second.ToArray(), rbFrom.UnmanagedObject, rbTo.UnmanagedObject, 0, secres);
                // We can safely drop the Z-coord at this stage
                Extents2d window = new Extents2d(firres[0], firres[1], secres[0], secres[1]);

                //Object SysVarBackPlot = Application.GetSystemVariable("BACKGROUNDPLOT");
                //Application.SetSystemVariable("BACKGROUNDPLOT", 0);
                Transaction tr = db.TransactionManager.StartTransaction();
                using (tr)
                {
                    // We'll be plotting the current layout
                    BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForRead);

                    // 定义过滤条件，设置仅选择BlockReference

                    //SelectionFilter filter = new SelectionFilter(new TypedValue[]
                    //{
                    //    new TypedValue((int)DxfCode.Start, "TEXT") // "INSERT"代表图块引用
                    //});
                    // 使用选取窗口和过滤条件进行选择
                    PromptSelectionResult selectionResult = ed.SelectCrossingWindow(first, second);

                    // 检查选择结果
                    if (selectionResult.Status != PromptStatus.OK)
                    {
                        ed.WriteMessage("\n未选择对象或操作取消。");
                        return;
                    }
                    //Dictionary<String, String> fieldDict = new Dictionary<string, string>();
                    selectedProcessName = "";
                    SelectionSet sSet = selectionResult.Value;
                    ObjectId[] selectedIds = sSet.GetObjectIds();  // 获取选择对象的ObjectiID数组.
                    foreach (ObjectId objId in selectedIds)
                    {
                        Entity entity = tr.GetObject(objId, OpenMode.ForRead) as Entity;

                        if (entity is BlockReference)
                        {
                            BlockReference blockRef = entity as BlockReference;
                            // 获取块引用所在的图层
                            string layerName = blockRef.Layer;
                            // 获取块的名称
                            string blockName = blockRef.Name;
                            // 输出块引用的信息
                            ed.WriteMessage("\n在图层 {0} 找到块引用: {1}", layerName, blockName);
                            Dictionary<string, Dictionary<string, string>> productProcessResult = new Dictionary<string, Dictionary<string, string>>();
                            string productcode = "";
                            // 遍历块引用中的所有属性
                            foreach (ObjectId attId in blockRef.AttributeCollection)
                            {
                                AttributeReference attRef = (AttributeReference)tr.GetObject(attId, OpenMode.ForRead);
                                if (attRef.Tag == GValues.BlockField_SemiProductCode ) //"图号"
                                {
                                    productcode = attRef.TextString;
                                }
                                if (attRef.Tag.IndexOf("製程") != -1)
                                {
                                    result[attRef.Tag] = attRef.TextString;
                                }
                                ed.WriteMessage("\n  属性标签: {0}, 属性值: {1}", attRef.Tag, attRef.TextString);
                            }
                            productProcessResult[productcode] = result;
                            productProcessResultList.Add(productProcessResult);

                        }

                        if (entity is Table)
                        {

                            Table table = entity as Table;
                            // 你现在可以使用table对象了
                            // ...
                            processHandleId = table.Handle.Value.ToString();
                            if (table.XData != null)
                            {
                                Dictionary<String, String> xDataDict = new Dictionary<string, string>();
                                String tableType = "none";
                                ResultBuffer rb = table.XData; // 获取实体的扩展数据

                                // 遍历ResultBuffer以查看数据
                                foreach (TypedValue tv in rb)
                                {
                                    switch ((DxfCode)tv.TypeCode)
                                    {
                                        case DxfCode.ExtendedDataRegAppName:
                                            var a = tv.Value.ToString();
                                            ed.WriteMessage("\n APP Code :" + a);
                                            break;
                                        case DxfCode.ExtendedDataAsciiString:
                                            var b = tv.Value.ToString();
                                            if (b.IndexOf("tableType:") != -1)
                                            {
                                                String[] cc = b.Split(':');
                                                if (cc[1] == "processSop")
                                                {
                                                    tableType = "processSop";
                                                    xDataDict["processSop"] = "true"; //SOP图纸表格
                                                    xDataDict["tableHandleId"] = processHandleId;
                                                }
                                                if (cc[1] == "processBom")
                                                {
                                                    tableType = "processBom";
                                                    xDataDict["processBom"] = "true"; //工艺图纸表格
                                                    xDataDict["tableHandleId"] = processHandleId;
                                                }
                                                if (cc[1] == "productBom")
                                                {
                                                    tableType = "productBom";
                                                    xDataDict["productBom"] = "true"; //产品图纸表格
                                                    xDataDict["tableHandleId"] = processHandleId;
                                                }
                                            }
                                            else if (b.IndexOf("processName:") != -1)
                                            {
                                                ed.WriteMessage("\n Process Name :" + b);
                                                String[] cc = b.Split(':');
                                                selectedProcessName = cc[1];
                                                xDataDict["processName"] = cc[1];
                                                xDataDict["tableHandleId"] = processHandleId;
                                            }
                                            else if (b.IndexOf("productCode:") != -1)
                                            {
                                                ed.WriteMessage("\n Product Code :" + b);
                                                String[] cc = b.Split(':');
                                                selectedProductCode = cc[1];
                                                xDataDict["productCode"] = cc[1];
                                                checkProductCode = true;
                                            }
                                            else
                                            {
                                                ed.WriteMessage("\n Product Code :" + b);
                                                selectedProductCode = b;
                                                checkProductCode = true;
                                                xDataDict["productCode"] = b;
                                                xDataDict["oldTable"] = "true";
                                                tableType = "oldTable";
                                                xDataDict["tableHandleId"] = processHandleId;
                                            }
                                            break;
                                        // 其他类型的DXF组码...

                                    }
                                }
                                tableDict[tableType] = xDataDict;
                            }
                            else
                            {
                                ed.WriteMessage("\n实体没有扩展数据！");
                            }
                        }

                    }
                    if (!checkProductCode)
                    {
                        ed.WriteMessage("\n选择框内没有定义工艺数据！");
                        //return;
                    }
                    else
                    {
                        if (tableDict["productBom"]["productBom"] == "true" && tableDict["processBom"]["processBom"] == "false" && tableDict["processSop"]["processSop"] == "false")
                        {
                            ed.WriteMessage("\n选择框内没有定义工艺数据！");
                            //return;
                        }
                    }

                    if (selectedProductCode == "")
                    {
                        selectedProductCode = result["图号"];
                    }

                    Layout lo = (Layout)tr.GetObject(btr.LayoutId, OpenMode.ForRead);

                    if (PlotFactory.ProcessPlotState == ProcessPlotState.NotPlotting)
                    {
                        PlotEngine pe = PlotFactory.CreatePublishEngine();
                        using (pe)
                        {
                            PlotProgressDialog ppd = new PlotProgressDialog(false, 1, true);
                            using (ppd)
                            {
                                int numSheet = 1;
                                // Setting up the PlotProgress dialog
                                ppd.set_PlotMsgString(PlotMessageIndex.DialogTitle, "Custom Plot Progress");
                                ppd.set_PlotMsgString(PlotMessageIndex.CancelJobButtonMessage, "Cancel Job");
                                ppd.set_PlotMsgString(PlotMessageIndex.CancelSheetButtonMessage, "Cancel Sheet");
                                ppd.set_PlotMsgString(PlotMessageIndex.SheetSetProgressCaption, "Sheet Set Progress");
                                ppd.set_PlotMsgString(PlotMessageIndex.SheetProgressCaption, "Sheet Progress");
                                ppd.LowerPlotProgressRange = 0;
                                ppd.UpperPlotProgressRange = 100;
                                ppd.PlotProgressPos = 0;


                                ppd.OnBeginPlot();
                                ppd.IsVisible = true;
                                pe.BeginPlot(ppd, null);

                                ppd.StatusMsgString = "Plotting block 1";
                                ppd.OnBeginSheet(); //????
                                ppd.LowerSheetProgressRange = 0;
                                ppd.UpperSheetProgressRange = 100;
                                ppd.SheetProgressPos = 0;

                                PlotInfoValidator piv = new PlotInfoValidator();
                                piv.MediaMatchingPolicy = MatchingPolicy.MatchEnabled;
                                PlotPageInfo ppi = new PlotPageInfo();
                                PlotInfo pi = new PlotInfo();
                                //BlockReference blk = gblk.BlockRef;
                                //Layout lo = btr.LayoutObj;

                                //// Getting coodinates of window to plot
                                //Extents3d ext = (Extents3d)blk.Bounds;
                                //Point3d first = ext.MaxPoint;
                                //Point3d second = ext.MinPoint;
                                //ResultBuffer rbFrom = new ResultBuffer(new TypedValue(5003, 1)), rbTo = new ResultBuffer(new TypedValue(5003, 2));
                                //double[] firres = new double[] { 0, 0, 0 };
                                //double[] secres = new double[] { 0, 0, 0 };
                                //acedTrans(first.ToArray(), rbFrom.UnmanagedObject, rbTo.UnmanagedObject, 0, firres);
                                //acedTrans(second.ToArray(), rbFrom.UnmanagedObject, rbTo.UnmanagedObject, 0, secres);
                                //Extents2d window = new Extents2d(firres[0], firres[1], secres[0], secres[1]);

                                // We need a PlotSettings object based on the layout settings which we then customize
                                PlotSettings ps = new PlotSettings(lo.ModelType);
                                //ps.PlotPlotStyles = true;
                                // Specify the plot options

                                LayoutManager.Current.CurrentLayout = lo.LayoutName;
                                pi.Layout = lo.Id;
                                ps.CopyFrom(lo);
                                ps.PrintLineweights = true;
                                ps.PlotTransparency = false;
                                ps.PlotPlotStyles = true;
                                ps.DrawViewportsFirst = true;
                                ps.ShowPlotStyles = true;
                                //PlotStyleTable = GetVauleFromArray("CtbThinnerLinesName")
                                // The PlotSettingsValidator helps create a valid PlotSettings object
                                PlotSettingsValidator psv = PlotSettingsValidator.Current;
                                psv.SetPlotConfigurationName(ps, PrinterName, PaperSize);
                                psv.RefreshLists(ps);
                                psv.SetPlotWindowArea(ps, window);
                                psv.SetPlotType(ps, Autodesk.AutoCAD.DatabaseServices.PlotType.Window);
                                psv.SetUseStandardScale(ps, true);
                                psv.SetStdScaleType(ps, StdScaleType.ScaleToFit);
                                psv.SetPlotRotation(ps, PlotRotation.Degrees090);
                                psv.SetCurrentStyleSheet(ps, "monochrome.ctb");

                                psv.SetPlotCentered(ps, true);

                                pi.OverrideSettings = ps;
                                piv.Validate(pi);
                                if (selectedProcessName != "")
                                {
                                    OutPath = GValues.pdfPath + "\\" + selectedProductCode + "-process-" + selectedProcessName + "-" + tableDict["processSop"]["tableHandleId"] + ".pdf";
                                }
                                else
                                {
                                    OutPath = GValues.pdfPath + "\\" + selectedProductCode + ".pdf";
                                }

                                pe.BeginDocument(pi, doc.Name, null, 1, true, OutPath); // Create document for the first page

                                // Plot the window
                                pe.BeginPage(ppi, pi, true, null);
                                pe.BeginGenerateGraphics(null);
                                ppd.SheetProgressPos = 50;
                                pe.EndGenerateGraphics(null);

                                // Finish the sheet
                                pe.EndPage(null);
                                ppd.SheetProgressPos = 100;
                                ppd.PlotProgressPos = 100; //+= Convert.ToInt32(100 / BlocksToPlot.Count);
                                ppd.OnEndSheet();
                                // Finish the document and finish the plot
                                pe.EndDocument(null);

                                ppd.PlotProgressPos = 100;
                                ppd.OnEndPlot();
                                pe.EndPlot(null);
                                ed.WriteMessage("\nPlot completed successfully!\n\n");
                                ps.Dispose();
                                pe.Dispose();
                                ppd.Dispose();
                            }
                        }
                    }
                    else
                    {
                        ed.WriteMessage("\nAnother plot is in progress.\n\n");
                    }
                    tr.Commit();
                    tr.Dispose();
                    //BomForm bomForm = new BomForm();
                    //bomForm.TT7SaveBomFormData(selectedProductCode, result);

                }

            }
            catch (Autodesk.AutoCAD.Runtime.Exception e)
            {

            }
            finally
            {

            }
        }
    }
}
